import os
import argparse
from pathlib import Path
from PIL import Image
import win32com.client  # 仅Windows可用，用于Office格式转换

def convert_images(input_dir, output_dir, target_format, recursive=False):
    """批量转换图片格式"""
    supported_formats = {'jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff'}
    target_format = target_format.lower()
    
    if target_format not in supported_formats:
        print(f"不支持的图片格式: {target_format}")
        return
    
    # 创建输出目录
    Path(output_dir).mkdir(parents=True, exist_ok=True)
    
    # 图片扩展名
    image_extensions = [f'.{ext}' for ext in supported_formats if ext != target_format]
    
    # 搜索文件
    count = 0
    for ext in image_extensions:
        search_pattern = f'**/*{ext}' if recursive else f'*{ext}'
        for img_path in Path(input_dir).glob(search_pattern):
            try:
                # 打开图片
                with Image.open(img_path) as img:
                    # 处理PNG透明通道
                    if target_format == 'jpg' and img.mode in ('RGBA', 'LA'):
                        background = Image.new(img.mode[:-1], img.size, (255, 255, 255))
                        background.paste(img, img.split()[-1])
                        img = background
                    
                    # 构建输出路径
                    output_name = f"{img_path.stem}.{target_format}"
                    output_path = Path(output_dir) / output_name
                    
                    # 保存图片
                    img.save(output_path, target_format.upper())
                    count += 1
                    print(f"转换: {img_path.name} -> {output_name}")
            except Exception as e:
                print(f"转换失败 {img_path.name}: {str(e)}")
    
    print(f"\n图片转换完成，共处理 {count} 个文件")

def convert_office_files(input_dir, output_dir, target_format, recursive=False):
    """批量转换Office文档格式（仅Windows）"""
    if target_format not in ['pdf', 'docx', 'xlsx', 'pptx']:
        print(f"不支持的目标格式: {target_format}")
        return
    
    # 创建输出目录
    Path(output_dir).mkdir(parents=True, exist_ok=True)
    
    # 映射文件类型与COM对象
    office_mapping = {
        'doc': ('Word.Application', 17),        # 17 = PDF格式
        'docx': ('Word.Application', 17),
        'xls': ('Excel.Application', 57),        # 57 = PDF格式
        'xlsx': ('Excel.Application', 57),
        'ppt': ('PowerPoint.Application', 32),   # 32 = PDF格式
        'pptx': ('PowerPoint.Application', 32)
    }
    
    # 调整目标格式对应的保存代码
    if target_format == 'docx':
        office_mapping['doc'] = ('Word.Application', 16)  # 16 = docx格式
    elif target_format == 'xlsx':
        office_mapping['xls'] = ('Excel.Application', 51)  # 51 = xlsx格式
    elif target_format == 'pptx':
        office_mapping['ppt'] = ('PowerPoint.Application', 24)  # 24 = pptx格式
    
    count = 0
    # 处理每种文件类型
    for ext, (app_name, save_format) in office_mapping.items():
        search_pattern = f'**/*.{ext}' if recursive else f'*.{ext}'
        for file_path in Path(input_dir).glob(search_pattern):
            try:
                # 创建Office应用实例
                app = win32com.client.Dispatch(app_name)
                app.Visible = False  # 不显示窗口
                
                # 打开文件
                doc = app.Documents.Open(str(file_path)) if app_name == 'Word.Application' else \
                      app.Workbooks.Open(str(file_path)) if app_name == 'Excel.Application' else \
                      app.Presentations.Open(str(file_path))
                
                # 构建输出路径
                output_name = f"{file_path.stem}.{target_format}"
                output_path = str(Path(output_dir) / output_name)
                
                # 保存为目标格式
                if app_name == 'Word.Application':
                    doc.SaveAs2(output_path, FileFormat=save_format)
                elif app_name == 'Excel.Application':
                    doc.SaveAs(output_path, FileFormat=save_format)
                elif app_name == 'PowerPoint.Application':
                    doc.SaveAs(output_path, FileFormat=save_format)
                
                # 关闭文档和应用
                doc.Close()
                app.Quit()
                
                count += 1
                print(f"转换: {file_path.name} -> {output_name}")
            except Exception as e:
                print(f"转换失败 {file_path.name}: {str(e)}")
                try:
                    app.Quit()
                except:
                    pass
    
    print(f"\nOffice文档转换完成，共处理 {count} 个文件")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='批量文件格式转换工具')
    parser.add_argument('input', help='输入目录')
    parser.add_argument('output', help='输出目录')
    parser.add_argument('format', help='目标格式，如pdf、jpg、docx')
    parser.add_argument('--type', choices=['image', 'office'], required=True, 
                      help='文件类型：image（图片）或office（Office文档）')
    parser.add_argument('--recursive', action='store_true', help='递归处理子目录')
    
    args = parser.parse_args()
    
    # 检查依赖
    try:
        if args.type == 'image':
            from PIL import Image
        elif args.type == 'office':
            import win32com.client
    except ImportError as e:
        if args.type == 'image':
            print("请安装图片处理库: pip install pillow")
        else:
            print("请安装Office处理库: pip install pywin32")
        exit(1)
    
    # 执行转换
    if args.type == 'image':
        convert_images(args.input, args.output, args.format, args.recursive)
    else:
        convert_office_files(args.input, args.output, args.format, args.recursive)
